home *** CD-ROM | disk | FTP | other *** search
- {
- PETER BEEFTINK
-
- See below an XMS Unit I picked up somewhere. I must admit that I have never
- been successful at using it, but maybe you have more luck.
- }
-
- Unit MegaXMS;
-
- Interface
-
- Var
- Present : Boolean; {True if XMM driver is installed}
- XMSError : Byte; {Error number. if 0 -> no error}
-
- Function XMMPresent : Boolean;
- Function XMSErrorString(Error : Byte) : String;
- Function XMSMemAvail : Word;
- Function XMSMaxAvail : Word;
- Function GetXMMVersion : Word;
- Function GetXMSVersion : Word;
- Procedure MoveFromEMB(Handle : Word; Var Dest; BlockLength : LongInt);
- Procedure MoveToEMB(Var Source; Handle : Word; BlockLength : LongInt);
- Function EMBGetMem(Size : Word) : Word;
- Procedure EMBFreeMem(Handle : Word);
- Procedure EMBResize(Handle, Size : Word);
- Function GetAvailEMBHandles : Byte;
- Function GetEMBLock(Handle : Word) : Byte;
- Function GetEMBSize(Handle : Word) : Word;
- Function LockEMB(Handle : Word) : LongInt;
- Procedure UnlockEMB(Handle : Word);
- Function UMBGetMem(Size : Word; Var Segment : Word) : Word;
- Procedure UMBFreeMem(Segment : Word);
- Function GetA20Status : Boolean;
- Procedure DisableLocalA20;
- Procedure EnableLocalA20;
- Procedure DisableGlobalA20;
- Procedure EnableGlobalA20;
- Procedure HMAGetMem(Size : Word);
- Procedure HMAFreeMem;
- Function GetHMA : Boolean;
-
- Implementation
-
- Uses
- Dos;
-
- Const
- High = 1;
- Low = 2;
- NumberOfErrors = 27;
-
- ErrorNumber : Array [1..NumberOfErrors] Of Byte =
- ($80,$81,$82,$8E,$8F,$90,$91,$92,$93,$94,$A0,$A1,$A2,$A3,
- $A4,$A5,$A6,$A7,$A8,$A9,$AA,$AB,$AC,$AD,$B0,$B1,$B2);
-
- ErrorString : Array [0..NumberOfErrors] Of String = (
- 'Unknown error',
- 'Function no implemented',
- 'VDISK device driver was detected',
- 'A20 error occured',
- 'General driver errror',
- 'Unrecoverable driver error',
- 'High memory area does not exist',
- 'High memory area is already in use',
- 'DX is less than the ninimum of KB that Program may use',
- 'High memory area not allocated',
- 'A20 line still enabled',
- 'All extended memory is allocated',
- 'Extended memory handles exhausted',
- 'Invalid handle',
- 'Invalid source handle',
- 'Invalid source offset',
- 'Invalid destination handle',
- 'Invalid destination offset',
- 'Invalid length',
- 'Invalid overlap in move request',
- 'Parity error detected',
- 'Block is not locked',
- 'Block is locked',
- 'Lock count overflowed',
- 'Lock failed',
- 'Smaller UMB is available',
- 'No UMBs are available',
- 'Inavlid UMB segment number');
-
- Type
- XMSParamBlock= Record
- Length : LongInt;
- SHandle : Word;
- SOffset : Array [High..Low] Of Word;
- DHandle : Word;
- DOffset : Array [High..Low] Of Word;
- end;
-
- Var
- XMSAddr : Array [High..Low] Of Word; {XMM driver address 1=Low,2=High}
-
- Function XMMPresent: Boolean;
- Var
- Regs : Registers;
- begin
- Regs.AX := $4300;
- Intr($2F, Regs);
- XMMPresent := Regs.AL = $80;
- end;
-
- Function XMSErrorString(Error : Byte) : String;
- Var
- I, Index : Byte;
- begin
- Index := 0;
- For I := 1 To NumberOfErrors Do
- if ErrorNumber[I] = Error Then
- Index := I;
- XMSErrorString := ErrorString[Index];
- end;
-
- Function XMSMemAvail : Word;
- Var
- Memory : Word;
- begin
- XMSError := 0;
- if Not(Present) Then
- Exit;
- Asm
- Mov AH, 8
- Call [XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- Jmp @@2
- @@1:
- Mov Memory, DX
- @@2:
- end;
- XMSMemAvail := Memory;
- end;
-
- Function XMSMaxAvail : Word;
- Var
- Temp : Word;
- begin
- XMSError := 0;
- if Not(Present) Then
- Exit;
- Asm
- Mov AH, 8
- Call [XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- Jmp @@2
- @@1:
- Mov Temp, AX
- @@2:
- end;
- XMSMaxAvail := Temp;
- end;
-
- Function EMBGetMem(Size : Word) : Word;
- Var
- Temp : Word;
- begin
- XMSError := 0;
- if Not(Present) Then
- Exit;
- Asm
- Mov AH, 9
- Mov DX, Size
- Call [XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- Jmp @@2
- @@1:
- Mov Temp, DX
- @@2:
- end;
- EMBGetMem := Temp;
- end;
-
- Procedure EMBFreeMem(Handle : Word);
- begin
- XMSError := 0;
- if Not(Present) Then
- Exit;
- Asm
- Mov AH, 0Ah
- Mov DX, Handle
- Call [XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- @@1:
- end;
- end;
-
- Procedure EMBResize(Handle, Size : Word);
- begin
- XMSError := 0;
- if Not(Present) Then
- Exit;
- Asm
- Mov AH, 0Fh
- Mov DX, Handle
- Mov BX, Size
- Call [XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- @@1:
- end;
- end;
-
- Procedure MoveToEMB(Var Source; Handle : Word; BlockLength : LongInt);
- Var
- ParamBlock : XMSParamBlock;
- XSeg, PSeg,
- POfs : Word;
- begin
- XMSError := 0;
- if Not(Present) Then
- Exit;
- With ParamBlock Do
- begin
- Length := BlockLength;
- SHandle := 0;
- SOffset[High] := Ofs(Source);
- SOffset[Low] := Seg(Source);
- DHandle := Handle;
- DOffset[High] := 0;
- DOffset[Low] := 0;
- end;
- PSeg := Seg(ParamBlock);
- POfs := Ofs(ParamBlock);
- XSeg := Seg(XMSAddr);
-
- Asm
- Push DS
- Mov AH, 0Bh
- Mov SI, POfs
- Mov BX, XSeg
- Mov ES, BX
- Mov BX, PSeg
- Mov DS, BX
- Call [ES:XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- @@1:
- Pop DS
- end;
- end;
-
- Procedure MoveFromEMB(Handle : Word; Var Dest; BlockLength : LongInt);
- Var
- ParamBlock : XMSParamBlock;
- XSeg, PSeg,
- POfs : Word;
- begin
- XMSError := 0;
- if Not(Present) Then
- Exit;
- With ParamBlock Do
- begin
- Length := BlockLength;
- SHandle := Handle;
- SOffset[High] := 0;
- SOffset[Low] := 0;
- DHandle := 0;
- DOffset[High] := Ofs(Dest);
- DOffset[Low] := Seg(Dest);
- end;
- PSeg := Seg(ParamBlock);
- POfs := Ofs(ParamBlock);
- XSeg := Seg(XMSAddr);
-
- Asm
- Push DS
- Mov AH, 0Bh
- Mov SI, POfs
- Mov BX, XSeg;
- Mov ES, BX
- Mov BX, PSeg
- Mov DS, BX
- Call [ES:XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- @@1:
- Pop DS
- end;
- end;
-
- Function GetXMSVersion : Word;
- Var
- HighB, LowB : Byte;
- begin
- XMSError := 0;
- if Not(Present) Then
- Exit;
- Asm
- Mov AH, 0
- Call [XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- Jmp @@2
- @@1:
- Mov HighB, AH
- Mov LowB, AL
- @@2:
- end;
- GetXMSVersion := (HighB * 100) + LowB;
- end;
-
- Function GetXMMVersion : Word;
- Var
- HighB, LowB : Byte;
- begin
- XMSError := 0;
- if Not(Present) Then
- Exit;
- Asm
- Mov AH, 0
- Call [XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- Jmp @@2
- @@1:
- Mov HighB, BH
- Mov LowB, BL
- @@2:
- end;
- GetXMMVersion := (HighB * 100) + LowB;
- end;
-
- Function GetHMA : Boolean;
- Var
- Temp : Boolean;
- begin
- XMSError := 0;
- if Not(Present) Then
- Exit;
- Temp := False;
- Asm
- Mov AH, 0
- Call [XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- Jmp @@2
- @@1:
- Cmp DX, 0
- Je @@2
- Mov Temp, 1
- @@2:
- end;
- GetHMA := Temp;
- end;
-
- Procedure HMAGetMem(Size : Word);
- begin
- XMSError := 0;
- if Not(Present) Then
- Exit;
- Asm
- Mov AH, 1
- Mov DX, Size
- Call [XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- @@1:
- end;
- end;
-
- Procedure HMAFreeMem;
- begin
- XMSError := 0;
- if Not(Present) Then
- Exit;
- Asm
- Mov AH, 2
- Call [XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- @@1:
- end;
- end;
-
- Procedure EnableGlobalA20;
- begin
- XMSError := 0;
- if Not(Present) Then
- Exit;
- Asm
- Mov AH, 3
- Call [XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- @@1:
- end;
- end;
-
-
- Procedure DisableGlobalA20;
- begin
- XMSError := 0;
- if Not(Present) Then
- Exit;
- Asm
- Mov AH, 4
- Call [XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- @@1:
- end;
- end;
-
- Procedure EnableLocalA20;
- begin
- XMSError := 0;
- if Not(Present) Then Exit;
- Asm
- Mov AH, 5
- Call [XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- @@1:
- end;
- end;
-
- Procedure DisableLocalA20;
- begin
- XMSError := 0;
- if Not(Present) Then
- Exit;
- Asm
- Mov AH, 6
- Call [XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- @@1:
- end;
- end;
-
- Function GetA20Status : Boolean;
- Var
- Temp : Boolean;
- begin
- XMSError := 0;
- if Not(Present) Then
- Exit;
- Temp := True;
- Asm
- Mov AH, 6
- Call [XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- Or AX, AX
- Jne @@1
- Or BL, BL
- Jne @@2
- Mov Temp, 0
- Jmp @@1
- @@2:
- Mov XMSError, BL
- @@1:
- end;
- end;
-
- Function LockEMB(Handle : Word) : LongInt;
- Var
- Temp1,
- Temp2 : Word;
- Temp : LongInt;
- begin
- XMSError := 0;
- if Not(Present) Then
- Exit;
- Asm
- Mov AH, 0Ch
- Mov DX, Handle
- Call [XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- Jmp @@2
- @@1:
- Mov Temp1, DX
- Mov Temp2, BX
- @@2:
- end;
- Temp := Temp1;
- LockEMB := (Temp Shl 4) + Temp2;
- end;
-
- Procedure UnlockEMB(Handle : Word);
- begin
- XMSError := 0;
- if Not(Present) Then
- Exit;
- Asm
- Mov AH, 0Dh
- Mov DX, Handle
- Call [XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- @@1:
- end;
- end;
-
- Function GetEMBSize(Handle : Word) : Word;
- Var
- Temp : Word;
- begin
- XMSError := 0;
- if Not(Present) Then
- Exit;
- Asm
- Mov AH, 0Eh
- Mov DX, Handle
- Call [XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- Jmp @@2
- @@1:
- Mov Temp, DX
- @@2:
- end;
- GetEMBSize := Temp;
- end;
-
- Function GetEMBLock(Handle : Word) : Byte;
- Var
- Temp : Byte;
- begin
- XMSError := 0;
- if Not(Present) Then
- Exit;
- Asm
- Mov AH, 0Eh
- Mov DX, Handle
- Call [XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- Jmp @@2
- @@1:
- Mov Temp, BH
- @@2:
- end;
- GetEMBLock := Temp;
- end;
-
- Function GetAvailEMBHandles : Byte;
- Var
- Temp : Byte;
- begin
- XMSError := 0;
- if Not(Present) Then
- Exit;
- Asm
- Mov AH, 0Eh
- Call [XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- Jmp @@2
- @@1:
- Mov Temp, BL
- @@2:
- end;
- GetAvailEMBHandles := Temp;
- end;
-
- Function UMBGetMem(Size : Word; Var Segment : Word) : Word; {Actual size}
- Var
- Temp1, Temp2 : Word;
- begin
- XMSError := 0;
- if Not(Present) Then
- Exit;
- Asm
- Mov AH, 10h
- Mov DX, Size
- Call [XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- Jmp @@2
- @@1:
- Mov Temp2, BX
- @@2:
- Mov Temp1, DX
- end;
- Segment := Temp2;
- UMBGetMem := Temp1;
- end;
-
- Procedure UMBFreeMem(Segment : Word);
- begin
- XMSError := 0;
- if Not(Present) Then
- Exit;
- Asm
- Mov AH, 10h
- Mov DX, Segment
- Call [XMSAddr]
- Or AX, AX
- Jne @@1
- Mov XMSError, BL
- @@1:
- end;
- end;
-
- Var
- Regs : Registers;
- begin
- if Not(XMMPresent) Then
- begin
- WriteLn('XMS not supported!');
- Present := False;
- Exit;
- end;
- Present := True;
- With Regs Do
- begin
- AX := $4310;
- Intr($2F, Regs);
- XMSAddr[High] := BX;
- XMSAddr[Low] := ES;
- end;
- end.